package com.apes.framework.query;

import com.apes.framework.api.DomainService;
import com.apes.framework.callback.InputInter;
import com.apes.framework.jpa.Connector;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.query.lib.BaseQuery;
import com.apes.framework.query.lib.PubToolUtil;
import com.apes.framework.rop.session.SimpleSession;
import com.apestech.api.query.sys.SysSql;
import com.apestech.api.xml.esb.EsbUtil;
import com.apestech.formwork.xml.XmlQuery;
import com.apestech.framework.cache.Cache;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.db.callback.FieldValueCallback;
import com.apestech.framework.dictionary.DataDictionary;
import com.apestech.framework.json.JSON;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.sql.MakeCondition;
import com.apestech.framework.sql.callback.OSqlCallback;
import com.apestech.framework.util.DBUtil;
import com.apestech.framework.util.ReflectUtil;
import com.apestech.framework.util.StringUtil;
import com.apestech.framework.xml.plugin.modul.QryConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Service("queryService")
public class QueryService extends DomainService {

    @Autowired
    Connector connector;

    public void query(SimpleRequest param) throws RuntimeException {
        try {
            JSONObject json= PubToolUtil.getInput(param);
            json.put("postId", getPostId1(param));
            String queryId=json.getString("queryid");
            if(queryId!=null){
                int pos1=queryId.indexOf("$");
                boolean jpa=pos1>=0;
                if(jpa){
                    queryId=queryId.replace("$","");
                    json.put("jpa","true");
                }
                int pos=queryId.indexOf("#");
                if(pos>=0){
                    String reflect=queryId.substring(pos+1, queryId.length());
                    queryId=queryId.substring(0, pos);
                    Object t=ReflectUtil.getObject("com.apes.framework.callback."+reflect);
                    if(t!=null){
                        json=((InputInter)t).getInput(json);
                    }
                }
            }
            json.put("queryid", queryId);

            if("condition.bill.query".equals(queryId) || "condition.exec.query".equals(queryId)
                    || "condition.exec.query.stop".equals(queryId) ){
                queryForm(param);
                return;
            }
            json=PubToolUtil.getRole(json, json.getString("postId"));
            if(json.get("size")!=null && json.getInteger("size")>0) json.put("page",json.getInteger("page")+1);
            HttpServletResponse response=(HttpServletResponse)param.getRopRequestContext().getRawResponseObject();
            QryConfig config=PubToolUtil.getQryConfig(queryId);
            SysSql.query(json, response, PubToolUtil.getSession(getQryDB(config), connector.getConnection()), config);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void queryForm(SimpleRequest param) throws RuntimeException {  //EsbFormQuery调整
        try {
            JSONObject json= PubToolUtil.getInput(param);
            json.put("postId",getPostId1(param));
            json=PubToolUtil.getRole(json, json.getString("postId"));
            BaseQuery query=new BaseQuery(json);
            query.setSession(PubToolUtil.getSession(getQryDB(query.getConfig()), connector.getConnection()));
            query.query();
            HttpServletResponse response=(HttpServletResponse)param.getRopRequestContext().getRawResponseObject();
            QryConfig config=query.getConfig();
            SysSql.query(json, response, PubToolUtil.getSession(getQryDB(config), connector.getConnection()), config);
            //SysSql.query(query.getJson(), response, query.getSession(), query.getConfig());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void queryImpForm(SimpleRequest param) throws RuntimeException {
        try {
            JSONObject json= PubToolUtil.getInput(param);
            json.put("postId",getPostId1(param));
            json=PubToolUtil.getRole(json, json.getString("postId"));
            BaseQuery query=new BaseQuery(json);
            query.setSession(PubToolUtil.getSession(getQryDB(query.getConfig()), connector.getConnection()));
            HttpServletResponse response=(HttpServletResponse)param.getRopRequestContext().getRawResponseObject();
            json.put("table","EXE_CONDITION_IMPORT");
            if(json.get("CID")!=null){
                json.put("CONDITION_ID", json.get("CID"));
                json.put("DIMENSION_ID", json.get("MID"));
                if(json.get("DIMENSION_ID")==null){
                    json.remove("DIMENSION_ID");
                }
            }
            json.put("POSTID", json.get("postId"));
            OSqlCallback other=new OSqlCallback() {
                @Override
                public String getSql() throws Exception {
                    return " AND EXISTS\n" +
                            " (SELECT 1 FROM AUT_CONDITION X, AUT_ROLE_POSTS Y\n" +
                            "         WHERE X.ROLE_ID = Y.ROLE_ID AND X.CONDITION_ID = A.CONDITION_ID\n" +
                            "           AND Y.POST_ID = #{POSTID} AND X.AUT_CREATE = 1 ) ";
                }
            };
            json.put("OSqlCallback", other);
            SysSql.query(json, response, query.getSession(), query.getConfig());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void queryStopForm(SimpleRequest param) throws RuntimeException {
        try {
            JSONObject json= PubToolUtil.getInput(param);
            json.put("postId",getPostId1(param));
            json=PubToolUtil.getRole(json, json.getString("postId"));
            BaseQuery query=new BaseQuery(json);
            query.setSession(PubToolUtil.getSession(getQryDB(query.getConfig()), connector.getConnection()));
            HttpServletResponse response=(HttpServletResponse)param.getRopRequestContext().getRawResponseObject();
            json.put("table","EXE_CONDITION_STOP");
            if(json.get("CID")!=null){
                json.put("CONDITION_ID", json.get("CID"));
                json.put("DIMENSION_ID", json.get("MID"));
                if(json.get("DIMENSION_ID")==null){
                    json.remove("DIMENSION_ID");
                }
            }
            json.put("POSTID", json.get("postId"));
            OSqlCallback other=new OSqlCallback() {
                @Override
                public String getSql() throws Exception {
                    return " AND EXISTS\n" +
                            " (SELECT 1 FROM AUT_CONDITION X, AUT_ROLE_POSTS Y\n" +
                            "         WHERE X.ROLE_ID = Y.ROLE_ID AND X.CONDITION_ID = A.CONDITION_ID\n" +
                            "           AND Y.POST_ID = #{POSTID} AND X.AUT_STOP = 1 ) ";
                }
            };
            json.put("OSqlCallback", other);
            SysSql.query(json, response, query.getSession(), query.getConfig());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void downXls(SimpleRequest param) throws RuntimeException {
        try {
            HttpServletResponse response=(HttpServletResponse)param.getRopRequestContext().getRawResponseObject();
            JSONObject json= PubToolUtil.getInput(param);
            String queryId=json.getString("queryid");
            if("condition.bill.query".equals(queryId) || "condition.exec.query".equals(queryId)){
                json.put("postId",getPostId1(param));
                json=PubToolUtil.getRole(json, json.getString("postId"));
                BaseQuery query=new BaseQuery(json);
                query.setSession(PubToolUtil.getSession(getQryDB(query.getConfig()), connector.getConnection()));
                query.query();
                query.getConfig().setFieldValueCallback(new FieldValueCallback(){
                    @Override
                    public Object getValue(String field, Object value) throws Exception {
                        JSONObject m=EsbUtil.getDownData(field, StringUtil.castToString(value));
                        if(m!=null){
                            return m.get("name");
                        }
                        return value;
                    }
                });
                SysSql.queryXls(query.getJson(), response, query.getSession(), query.getConfig());
            } else {
                json=PubToolUtil.getRole(json, getPostId1(param));
                QryConfig config=PubToolUtil.getQryConfig(queryId);
                SysSql.queryXls(json, response, PubToolUtil.getSession(getQryDB(config), connector.getConnection()), config);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public JSONObject downXlsFile(SimpleRequest param) throws RuntimeException {
        try {
            JSONObject json= PubToolUtil.getInput(param);
            String queryId=json.getString("queryid");
            if("condition.bill.query".equals(queryId) || "condition.exec.query".equals(queryId)){
                json.put("postId",getPostId1(param));
                json=PubToolUtil.getRole(json, json.getString("postId"));
                BaseQuery query=new BaseQuery(json);
                query.setSession(PubToolUtil.getSession(getQryDB(query.getConfig()), connector.getConnection()));
                query.query();
                query.getConfig().setFieldValueCallback(new FieldValueCallback(){
                    @Override
                    public Object getValue(String field, Object value) throws Exception {
                        JSONObject m=EsbUtil.getDownData(field, StringUtil.castToString(value));
                        if(m!=null){
                            return m.get("name");
                        }
                        return value;
                    }
                });
                return SysSql.queryXls(query.getJson(), query.getSession(), query.getConfig());
            } else {
                json=PubToolUtil.getRole(json, getPostId1(param));
                QryConfig config=PubToolUtil.getQryConfig(queryId);
                return SysSql.queryXls(json, PubToolUtil.getSession(getQryDB(config), connector.getConnection()), config);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public JSONObject downXlsFile(JSONObject json) throws RuntimeException {
        try {
            String queryId = json.getString("queryid");
            json = PubToolUtil.getRole(json, json.getString("postId"));
            QryConfig config = PubToolUtil.getQryConfig(queryId);
            return SysSql.queryXls(json, PubToolUtil.getSession(getQryDB(config), connector.getConnection()), config);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void importXls(SimpleRequest param) throws RuntimeException {
        try {
            JSONObject json= PubToolUtil.getInput(param);
            String fileName=json.getString("fileName");
            String importId=json.getString("importId");  //策略调整单相关做单独处理，其它模式走统一入口

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void queryForTable(SimpleRequest param) throws RuntimeException {
        try {
            JSONObject json= PubToolUtil.getInput(param);
            HttpServletResponse response=(HttpServletResponse)param.getRopRequestContext().getRawResponseObject();
            json.put("nb_sql", SysSql.getTableSql(json, PubToolUtil.getSession(null, connector.getConnection())));
            SysSql.query(json, response, PubToolUtil.getSession(null, connector.getConnection()), null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String getTableSelect(SimpleRequest param) throws RuntimeException {
        try {
            JSONObject json= PubToolUtil.getInput(param);
            return SysSql.getTableSql(json, PubToolUtil.getSession(null, connector.getConnection()));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public void refreshQueryXml(SimpleRequest param) throws RuntimeException {
        try {
            JSONObject json= PubToolUtil.getInput(param);
            String queryId=json.getString("queryId");
            XmlQuery query=new XmlQuery(queryId);
            query.clearCache();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public int getDBConnectCount(SimpleRequest param) throws RuntimeException {
        try {
            return DBUtil.getActiveCount(PubToolUtil.getDBName());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public void iniDictionary(SimpleRequest param) throws RuntimeException {
        try {
            SqlSession session=PubToolUtil.getSession(null, connector.getConnection());
            DataDictionary.iniDictionary(session);;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private String getPostId1(SimpleRequest request) {
        SimpleSession session = (SimpleSession) request.getRopRequestContext().getSession();
        if (session != null) return session.getPostId();
        return null;
    }

    private String getQryDB(QryConfig config){
        String sysId=null;
        if(config!=null) sysId=config.getSysId();
        return sysId;
    }

    /***
     * 对导出条件进行手动添加（例如从当前登录人员取对应的行政部门以及岗位）
     * @param request
     * @return
     */
    public JSONObject customAction(SimpleRequest request){
        try {
            String body=(String)request.getData();
            JSONObject json= JSON.toJSON(body);
            if(!json.getBooleanValue("customAction")){
                return json;
            }else{
                return invoke(json.getString("queryid"),json);
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /***
     * 自定义查询（目前用于跨库查询）
     * @param request
     * @return
     */
    public Object customQuery(SimpleRequest request) {
        try {
            Map tempMap= request.getMap();
            tempMap.put("customQuery", false);
            return this.invoke(request.get("queryid"), tempMap);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void delDictTable(SimpleRequest request) {
        try {
            SqlSession session=PubToolUtil.getSession(null, connector.getConnection());
            JSONObject input=PubToolUtil.getInput(request);
            String key=input.getString("key");
            Cache.removeKey(key);
            session.delTabCache(key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
